import { Router } from 'express';
import Paths from '@src/common/constants/Paths';
import { prisma } from '@src/common/database';
import { jsonResponse } from '@src/common/util/bigint-serializer';
import { Prisma } from '@prisma/client';

const router = Router();
import { getWithdrawSettings, calcWithdrawAmount } from '@src/common/settings'
import { canWithdraw } from '@src/utils/memberLevel'


// 复用 auth 的 cookie 名
const SESSION_COOKIE = 'sid';

async function getCurrentUser(req: any) {
  try {
    const sid = req.cookies?.[SESSION_COOKIE];
    if (!sid) return null;
    const sess = await prisma.userSession.findUnique({ where: { id: BigInt(sid) } });
    if (!sess || new Date(sess.expiredAt) < new Date()) return null;
    const user = await prisma.user.findUnique({ where: { id: sess.userId } });
    return user;
  } catch {
    return null;
  }
}

// GET /api/pay/bank-accounts/active - 활성화된 은행 계좌 목록
router.get(Paths.Pay.BankAccounts + '/active', async (_req, res) => {
  try {
    const accounts = await prisma.bankAccount.findMany({ where: { isActive: true }, orderBy: { createdAt: 'desc' } });
    return jsonResponse(res, { accounts });
  } catch (err) {
    console.error('활성화된 은행 계좌 조회 실패:', err);
    return res.status(500).json({ error: '활성화된 은행 계좌 조회에 실패했습니다' });
  }
});

// GET /api/pay/withdraw-config - 출금 설정
router.get('/withdraw-config', async (_req, res) => {
  try {
    const s = await getWithdrawSettings()
    // banks 필드 제거 (사용자가 더 이상 은행을 선택할 필요가 없음)
    const { banks: _banks, ...config } = s
    return jsonResponse(res, config)
  } catch (err) {
    console.error('출금 설정 조회 실패:', err)
    return res.status(500).json({ error: '출금 설정을 가져오는데 실패했습니다' })
  }
})

// POST /api/pay/recharges - 충전 신청 생성 (은행 이체)
router.post(Paths.Pay.Recharges, async (req, res) => {
  try {
    const user = await getCurrentUser(req);
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' });

    const { amountDecimal, pointsCredited, bankAccountId, evidenceUrl, purchaserName, purchaserPhone } = req.body ?? {};

    const amt = amountDecimal ? String(amountDecimal) : null;
    const pts = pointsCredited ? BigInt(pointsCredited) : null;
    if (!amt || !pts || pts <= BigInt(0)) {
      return res.status(400).json({ error: '충전 금액과 포인트는 필수이며 0보다 커야 합니다' });
    }

    let accountId: bigint | null = null;
    if (bankAccountId) accountId = BigInt(bankAccountId);
    else {
      const acc = await prisma.bankAccount.findFirst({ where: { isActive: true }, orderBy: { createdAt: 'desc' } });
      accountId = acc ? acc.id : null;
    }

    const ref = `RCG-${new Date().toISOString().slice(0,10).replace(/-/g,'')}-${Math.random().toString(36).slice(2,8).toUpperCase()}`;

    const recharge = await prisma.recharge.create({
      data: {
        userId: user.id,
        method: 'bank_transfer',
        bankAccountId: accountId || undefined,
        amountDecimal: new Prisma.Decimal(amt),
        pointsCredited: pts,
        status: 'pending',
        referenceNo: ref,
        evidenceUrl: evidenceUrl || null,
        purchaserName: purchaserName ? String(purchaserName).slice(0, 50) : null,
        purchaserPhone: purchaserPhone ? String(purchaserPhone).slice(0, 30) : null,
      },
    });

    const account = accountId ? await prisma.bankAccount.findUnique({ where: { id: accountId } }) : null;

    return jsonResponse(res, { recharge, account });
  } catch (err) {
    console.error('충전 신청 생성 실패:', err);
    return res.status(500).json({ error: '충전 신청 생성에 실패했습니다' });
  }
});

// GET /api/pay/recharges - 현재 사용자 충전 목록 (선택적 상태)
router.get(Paths.Pay.Recharges, async (req, res) => {
  try {
    const user = await getCurrentUser(req);
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' });

    const { status } = req.query as any;
    const where: any = { userId: user.id };
    if (status) where.status = String(status);

    const list = await prisma.recharge.findMany({ where, orderBy: { createdAt: 'desc' } });
    return jsonResponse(res, list);
  } catch (err) {
    console.error('충전 목록 조회 실패:', err);
    return res.status(500).json({ error: '충전 목록을 가져오는데 실패했습니다' });
  }
});

// GET /api/pay/recharges/:id - 상태 조회
router.get(Paths.Pay.Recharges + '/:id', async (req, res) => {
  try {
    const user = await getCurrentUser(req);
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' });

    const { id } = req.params as any;
    const rec = await prisma.recharge.findUnique({ where: { id: BigInt(id) } });
    if (!rec || rec.userId !== user.id) return res.status(404).json({ error: '충전 신청을 찾을 수 없습니다' });

    return jsonResponse(res, rec);
  } catch (err) {
    console.error('충전 상세 조회 실패:', err);
    return res.status(500).json({ error: '충전 상세 정보를 가져오는데 실패했습니다' });
  }
});

// GET /api/pay/wallet - 현재 사용자 포인트 잔액
router.get('/wallet', async (req, res) => {
  try {
    const user = await getCurrentUser(req);
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' });

    const wallet = await prisma.userWallet.findUnique({ where: { userId: user.id } });
    return jsonResponse(res, { balancePoints: wallet?.pointsBalance || BigInt(0) });
  } catch (err) {
    console.error('지갑 조회 실패:', err);
    return res.status(500).json({ error: '지갑 조회에 실패했습니다' });
  }
});

// POST /api/pay/recharges/:id/evidence - 증빙 URL 업로드(간단 필드)
router.post(Paths.Pay.Recharges + '/:id/evidence', async (req, res) => {
  try {
    const user = await getCurrentUser(req);
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' });

    const { id } = req.params as any;
    const { evidenceUrl } = req.body ?? {};

    const rec = await prisma.recharge.findUnique({ where: { id: BigInt(id) } });
    if (!rec || rec.userId !== user.id) return res.status(404).json({ error: '충전 신청을 찾을 수 없습니다' });

    const updated = await prisma.recharge.update({ where: { id: rec.id }, data: { evidenceUrl: evidenceUrl || null } });
    return jsonResponse(res, updated);
  } catch (err) {
    console.error('증빙 업데이트 실패:', err);
    return res.status(500).json({ error: '증빙 업데이트에 실패했습니다' });
  }
});

// ======= Withdrawals（用户侧） =======
router.post('/withdrawals', async (req, res) => {
  try {
    const user = await getCurrentUser(req)
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' })



    // 检查会员等级是否有提现权限
    if (!canWithdraw(user.memberLevel)) {
      return res.status(403).json({ error: '현재 회원님은 등급제한으로 출금이 불가능합니다.' })
    }

    const { pointsToWithdraw, bankName, accountName, accountNumber, accountId } = req.body ?? {}
    const pts = pointsToWithdraw ? BigInt(pointsToWithdraw) : null
    if (!pts || pts <= BigInt(0)) return res.status(400).json({ error: '출금 포인트는 필수이며 0보다 커야 합니다' })

    // 은행 정보 확인
    if (!bankName || !accountName || !accountNumber || !accountId) {
      return res.status(400).json({ error: '은행명, 계좌주, 계좌번호, 신분증번호는 필수 항목입니다' })
    }

    const s = await getWithdrawSettings()
    if (pts < BigInt(s.minPoints || 0)) return res.status(400).json({ error: `최소 출금 포인트는 ${s.minPoints}입니다` })

    // 사용자 잔액 확인
    const wallet = await prisma.userWallet.findUnique({ where: { userId: user.id } })
    if (!wallet || wallet.pointsBalance < pts) {
      return res.status(400).json({ error: '잔액이 부족합니다' })
    }

    const { net } = calcWithdrawAmount(pts, s)
    const ref = `WDL-${new Date().toISOString().slice(0,10).replace(/-/g,'')}-${Math.random().toString(36).slice(2,8).toUpperCase()}`

    const rec = await prisma.withdrawal.create({
      data: {
        userId: user.id,
        pointsToWithdraw: pts,
        amountDecimal: new Prisma.Decimal(String(net)),
        status: 'pending',
        referenceNo: ref,
        // 사용자가 입력한 은행 정보
        payoutBankName: String(bankName).trim(),
        payoutAccountName: String(accountName).trim(),
        payoutAccountNumber: String(accountNumber).trim(),
        payoutAccountId: String(accountId).trim(),
      }
    })
    return jsonResponse(res, rec)
  } catch (err) {
    console.error('출금 생성 실패:', err)
    return res.status(500).json({ error: '출금 신청에 실패했습니다' })
  }
})

router.get('/withdrawals', async (req, res) => {
  try {
    const user = await getCurrentUser(req)
    if (!user) return res.status(401).json({ error: '로그인이 필요합니다' })
    const { status } = req.query as any
    const where: any = { userId: user.id }
    if (status) where.status = String(status)
    const list = await prisma.withdrawal.findMany({ where, orderBy: { createdAt: 'desc' } })
    return jsonResponse(res, list)
  } catch (err) {
    console.error('출금 목록 조회 실패:', err)
    return res.status(500).json({ error: '출금 목록을 가져오는데 실패했습니다' })
  }
})

router.get('/withdrawals/:id', async (req, res) => {
  try {
    const user = await getCurrentUser(req)
    if (!user) return res.status(401).json({ error: '未登录' })
    const { id } = req.params as any
    const rec = await prisma.withdrawal.findUnique({ where: { id: BigInt(id) } })
    if (!rec || rec.userId !== user.id) return res.status(404).json({ error: '提现单不存在' })
    return jsonResponse(res, rec)
  } catch (err) {
    console.error('获取提现详情失败:', err)
    return res.status(500).json({ error: '获取提现详情失败' })
  }
})

// GET /api/pay/point-packages - 활성화된 포인트 패키지 가져오기(공개 API)
router.get(Paths.Pay.PointPackages, async (_req, res) => {
  try {
    const packages = await prisma.pointPackage.findMany({
      where: { isActive: true },
      orderBy: [{ sortOrder: 'asc' }, { createdAt: 'desc' }]
    });
    return jsonResponse(res, packages);
  } catch (err) {
    console.error('포인트 패키지 가져오기 실패:', err);
    return res.status(500).json({ error: '포인트 패키지 가져오기 실패' });
  }
});

export default router;

